package com.teaphy.demo;

import com.teaphy.annotations.Explain;
import com.teaphy.annotations.NotNull;
import com.teaphy.data.Student;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.Arrays;

/**
 * @author teaphy
 * @desc
 * @time 2019-03-11 10:24
 */
public class FieldDemo {
	public static void main(String[] args) {
		Student student = new Student();
		Class<Student> clzStudent = Student.class;
		student.addr = "山东青岛";

		try {
			// 从Student.Class中获取字段"addr"
			Field fieldAddr = clzStudent.getField("addr");

			// 1. Annotation
			// 1.1 getAnnotations() -> Annotation[]: 返回该Field的注解列表。
			Annotation[] annotations =  fieldAddr.getAnnotations();
			System.out.println("getAnnotations(): " + Arrays.toString(annotations));

			// 1.2 getAnnotation(Class) -> 判断该Field是否被指定的Annotation注解。
			// 如果是，返回该注解，否则，返回null.
			Explain annoExplain = fieldAddr.getAnnotation(Explain.class);
			if (null == annoExplain) {
				System.out.println("当前Field-'addr'没有被Explain注解：" + annoExplain);
			} else {
				System.out.println("当前Field-'addr'被Explain注解：" + annoExplain);
			}

			NotNull annoNotNull = fieldAddr.getAnnotation(NotNull.class);
			if (null == annoNotNull) {
				System.out.println("当前Field-'addr'没有被NotNull注解：" + annoNotNull );
			} else {
				System.out.println("当前Field-'addr'被NotNull注解：" + annoNotNull);
			}

			// 1.3 getDeclaredAnnotations() -> 返回此Method的直接注解
			Annotation[] declaredAnnotations = fieldAddr.getDeclaredAnnotations();
			System.out.println("getDeclaredAnnotations(): " + Arrays.toString(declaredAnnotations));

			// 1.4 getAnnotationsByType(Class) -> 返回与此元素关联的指定注解列表。
			Explain[] explainByType = fieldAddr.getAnnotationsByType(Explain.class);
			System.out.println("getAnnotationsByType(Explain.class): " + Arrays.toString(explainByType));
			NotNull[] notNullByType = fieldAddr.getAnnotationsByType(NotNull.class);
			System.out.println("getAnnotationsByType(NotNull.class): " + Arrays.toString(notNullByType));

			// 2. Value
			// 2.1 get
			String addr = (String) fieldAddr.get(student);
			System.out.println("fieldAddr.get(student): " + addr);
			// 2.1 set
			fieldAddr.set(student, "山东青岛崂山");
			String addrAfterSet = (String) fieldAddr.get(student);
			System.out.println("fieldAddr.get(student): " + addrAfterSet);

			// 3. 声明的Class
			// 3.1 getDeclaringClass() -> Class<?> : 返回表示声明Filed的Class对象(类或接口)。
			Class<?> declaringClass = fieldAddr.getDeclaringClass();
			System.out.println("getDeclaringClass(): " + declaringClass);

			// 4. 数据类型
			// 4.1 getGenericType() -> Type: 返回Field的数据类型
			Type genericType = fieldAddr.getGenericType();
			System.out.println("getGenericType(): " + genericType);
			// 4.2 getType() -> Class<?>：返回一个Class对象，该对象表示Field(字段)的声明类型
			Class<?> type = fieldAddr.getType();
			System.out.println("getType(): " + type);

			// 5 修饰符类型
			// 5.1 getModifiers() -> int：获取Field的修饰符类型
			int modifiers = fieldAddr.getModifiers();
			String mod = Modifier.toString(modifiers);
			System.out.println("modifier: " + mod);

			// 6. 字符串
			String name = fieldAddr.getName();
			System.out.println("getName(): " + name);

			String genericString = fieldAddr.toGenericString();
			System.out.println("toGenericString(): " + genericString);

			String toString = fieldAddr.toString();
			System.out.println("toString(): " + toString);
		} catch (NoSuchFieldException | IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}
